package com.mo.ld.activity.gate

import com.drake.net.Net
import com.drake.net.NetConfig
import com.drake.net.exception.ResponseException
import com.drake.net.interceptor.RequestInterceptor
import com.drake.net.interfaces.NetCallback
import com.drake.net.interfaces.NetErrorHandler
import com.drake.net.okhttp.setConverter
import com.drake.net.okhttp.setErrorHandler
import com.drake.net.okhttp.setLog
import com.drake.net.okhttp.setRequestInterceptor
import com.drake.net.request.BaseRequest
import com.drake.net.request.BodyRequest
import com.drake.net.request.UrlRequest
import com.mo.lib.http.GsonConverter2
import com.mo.lib.http.KCallBack
import com.mo.lib.http.LogInterceptor
import com.mo.lib.utils.Hex
import com.mo.lib.utils.KLog
import com.xuexiang.xutil.security.EncryptUtils
import okhttp3.Call
import org.json.JSONException
import org.json.JSONObject
import java.io.IOException
import java.io.UnsupportedEncodingException
import java.security.InvalidKeyException
import java.security.NoSuchAlgorithmException
import java.util.*
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
import kotlin.collections.HashMap
import kotlin.collections.LinkedHashSet
import kotlin.collections.ArrayList as ArrayList1

/**
 * @ author：mo
 * @ data：2021/12/20:8:59
 * @ 功能：
 */
val GateKey = "502F396B-4002-4877-B906-55D61DA90C02"
val GateSecret = "b5d9aafff1762b6059e7e990780e466dee2d6c402dcec680ffb6c2b1e292ebe2"

//val GateKeyAndSecret={"apiKey":"502F396B-4002-4877-B906-55D61DA90C02","secretKey":"b5d9aafff1762b6059e7e990780e466dee2d6c402dcec680ffb6c2b1e292ebe2"}
fun getPairs(callBack: KCallBack<List<String>>) {
    Net.get("pairs") {
        setTag("获取所有")
    }.enqueue(callBack)
}

fun getCandlestick(curr: String, group_sec: Int, hour: Int, callBack: MutableList<GateCandleBean>.() -> Unit) {
    Net.get("candlestick2/$curr?group_sec=$group_sec&range_hour=$hour") { //        Net.get("candlestick2/"+curr+"_usdt?group_sec="+60*group_sec+"&range_hour=72") {
        setTag("k")
    }.enqueue(object : NetCallback<GateCandlestickBean>() {
        override fun onSuccess(call: Call, result: GateCandlestickBean) {
            val data = result.data.toList().sortedBy { it[0] } //  升序：sortedBy  降序：sortedByDescending
            val candleList = mutableListOf<GateCandleBean>()
            data.forEach {
                val add = GateCandleBean(it[0].toLong(), it[1].toDouble(), it[5].toDouble(), it[2].toDouble(), it[3].toDouble(), it[4].toDouble())
                candleList.add(add)
            }
            callBack.invoke(candleList)
        }

        override fun onFailure(call: Call, e: IOException) {
            super.onFailure(call, e)
            callBack.invoke(mutableListOf<GateCandleBean>())
        }


    })
}

fun initGate() {
    NetConfig.init("https://data.gateapi.io/api2/1/") {
        setConverter(GsonConverter2()).setRequestInterceptor(object : RequestInterceptor {
            override fun interceptor(request: BaseRequest) {
                when (request) {
                    is BodyRequest -> {
                        request.addHeader("Key", GateKey)
                        val formBody = request.formBody
                        val build = formBody.build()
                        var mac: Mac? = null
                        var key: SecretKeySpec? = null
                        var postData = ""
                        for (i in 0 until build.size) {
                            if (postData.isNotEmpty()) {
                                postData += "&";
                            }
                            postData += build.name(i) + "=" + build.value(i);
                        }
                        try {
                            key = SecretKeySpec(GateSecret.toByteArray(), "HmacSHA512")
                        } catch (uee: UnsupportedEncodingException) {
                            System.err.println("Unsupported encoding exception: " + uee.toString())
                        }

                        try {
                            mac = Mac.getInstance("HmacSHA512")
                        } catch (nsae: NoSuchAlgorithmException) {
                            System.err.println("No such algorithm exception: " + nsae.toString())
                        }

                        try {
                            mac!!.init(key)
                        } catch (ike: InvalidKeyException) {
                            System.err.println("Invalid key exception: " + ike.toString())
                        }
                        request.addHeader("Sign", Hex.encodeHexStr(mac?.doFinal(postData.toByteArray())))
                    }
                    is UrlRequest -> {
                        val url = request.httpUrl.toString()
                        if (url.contains("?")) {
                            val split = url.split("?")[1]

                            val spilit2 = split.split("&")
                            val hashMap = HashMap<String, String>()
                            for (item in spilit2) {
                                val itemSplit = item.split("=")
                                hashMap.put(itemSplit[0], itemSplit[1])
                            }
                            request.addHeader("sign", EncryptUtils.encryptHmacSHA512ToString(hashMap.toString(), GateSecret))
                        }
                    }
                }

            }
        }).addInterceptor(LogInterceptor())
        setErrorHandler(object : NetErrorHandler {
            override fun onError(e: Throwable) {
                when (e) {
                    is ResponseException -> {
                        if (e.message!!.contains("invalid request")) {
                            KLog.i("无效的请求：${e}，请检查接口拼写!")
                        }
                    }
                    else -> {
                        super.onError(e)
                    }
                }
            }

        }).setLog(true)
    }

}

fun getBuy(currencyPair: String, rate: String, amount: String, callBack: KCallBack<GateCandlestickBean>) {
    Net.get("private/buy") {
        setTag("买入")
        param("currencyPair", currencyPair + "_usdt")
        param("rate", rate)
        param("amount", amount)
        param("orderType", "gtc")
    }.enqueue(callBack)
}

fun getSell(currencyPair: String, rate: String, amount: String, callBack: KCallBack<String>) {
    Net.post("private/sell") {
        setTag("卖出")
        param("currencyPair", currencyPair)
        param("rate", rate)
        param("amount", amount)
        param("orderType", "gtc")
    }.enqueue(callBack)
}

fun getBalances(resultList: ((a1: ArrayList<GateCoins>, a2: ArrayList<GateCoins>) -> Unit)) {
    Net.post("private/balances") {
        setTag("获取帐号资金余额")
    }.enqueue(object : NetCallback<String>() {
        override fun onSuccess(call: Call, result: String) {
            val resultBean = BalancesBean(arrayListOf(), arrayListOf())
            var jsonObject: JSONObject? = null
            val balancesList = arrayListOf<String>()
            try {
                jsonObject = JSONObject(result)
                val available = jsonObject.getJSONObject("available")
                for (item in available.keys()) {
                    val toDouble = available.optString(item).toDouble()
                    if (toDouble != 0.0) {
                        resultBean.available.add(GateCoins(item, toDouble.toString()))
                    }
                }
                val locked = jsonObject.getJSONObject("locked")
                for (item in locked.keys()) {
                    val toDouble = locked.optString(item).toDouble()
                    if (toDouble != 0.0) {
                        resultBean.locked.add(GateCoins(item, toDouble.toString()))
                    }
                }
                KLog.i(resultBean.available.size.toString() + "====" + resultBean.toString())
                resultList.invoke(resultBean.available, resultBean.locked)
            } catch (e: JSONException) {
                e.printStackTrace()
            }


        }
    })
}

fun getBalances2(resultList: (ArrayList1<String>.() -> Unit)) {
    Net.post("private/balances") {
        setTag("获取帐号资金余额")
    }.enqueue(object : NetCallback<String>() {
        override fun  onSuccess(call: Call,result: String) {
            var jsonObject: JSONObject? = null
            val balancesList = arrayListOf<String>()
            try {
                jsonObject = JSONObject(result)
                val available = jsonObject.getJSONObject("available")
                for (i in 0 until available.length()) {
                    val keys = available.keys()
                    while (keys.hasNext()) {
                        val next = keys.next()
                        if (next != "USDT") {
                            balancesList.add(next + "_USDT")
                        }
                    }
                }
                val locked = jsonObject!!.getJSONObject("locked")
                for (i in 0 until locked.length()) {
                    val keys = locked.keys()
                    while (keys.hasNext()) {
                        val next = keys.next()
                        if (next != "USDT") {
                            balancesList.add(next + "_USDT")
                        }

                    }
                }
                resultList.invoke(ArrayList1<String>(LinkedHashSet<String>(balancesList)))
            } catch (e: JSONException) {
                e.printStackTrace()
            }


        }
    })
}

fun getOpenOrders(orderBean: (OrderBean.() -> Unit)) {
    Net.post("private/openOrders") {
        setTag("获取我的当前挂单列表")
    }.enqueue(object : NetCallback<OrderBean>() {
        override fun onSuccess(call: Call,result: OrderBean) {
            orderBean.invoke(result)
        }
    })
}